#include "spa_types.h"
#include "TNode.h"
#include "AST.h"
#include "ProcTable.h"
#include <vector>
#include <iostream>

AST::AST(){
}
AST::~AST(){
	vector<RootNode>::const_iterator it;
	for (it = rnode_store.begin(); it != rnode_store.end(); ++it)
		delete it->node;
}

void AST::CreateAST(TNODE* root_node, PROCINDEX proc_index){
	RootNode rNode;
	rNode.node = root_node;
	rNode.proc_index = proc_index;
	this->rnode_store.push_back(rNode);
}

TNODE* AST::CreateNode(NODETYPE node_type){
	TNODE* new_node = new TNode(node_type,0);
	this->tnode_store.push_back(new_node);
	return new_node;
}

void AST::SetValue(TNODE* this_node, STRING value){
	if (this_node != NULL){
		this_node->value = value;
	}
}
void AST::SetStatementNumber(TNODE* this_node, INTEGER stmt_num){
	if (this_node != NULL){
		this_node->statement_number = stmt_num;
		stmt_to_tnode.insert(pair<INTEGER,TNODE*>(stmt_num,this_node));
	}
}
void AST::SetParentChildLink(TNODE* parent_node, TNODE* child_node, INTEGER nth_child){
	if (parent_node != NULL && child_node != NULL){
		parent_node->add_child(child_node,nth_child);
		child_node->parent_node = parent_node;
	}
}
void AST::SetRightSibling(TNODE* this_node, TNODE* right_node){
	if(this_node != NULL){
		this_node->right_sibling = right_node;
	}
}
TNODE* AST::GetRoot(PROCINDEX proc_index){
	for(unsigned int i=0;i<rnode_store.size();i++){
		if (rnode_store[i].proc_index == proc_index){
			return rnode_store[i].node;
		}
	}
	return NULL;
}
TNODE* AST::GetChild(TNODE* parent_node, INTEGER nth_position){
	if (parent_node != NULL){
		for (auto it=parent_node->child_nodes.begin() ; it != parent_node->child_nodes.end(); it++ )
			if (it->first == nth_position)
				return parent_node->child_nodes.find(nth_position)->second;
	}
	return NULL;
}
TNODE* AST::GetRightSibling(TNODE* this_node){
	if (this_node != NULL){
		return this_node->right_sibling;
	}
	return NULL;
}
STRING AST::GetValue(TNODE* this_node){
	if (this_node != NULL){
		return this_node->value;
	}
	return NULL;
}
NODETYPE AST::GetNodeType(TNODE* this_node){
	if (this_node != NULL){
		return this_node->node_type;
	}
	return _NULL;
}
INTEGER AST::GetStatementNumber(TNODE* this_node){
	if (this_node != NULL){
		return this_node->statement_number;
	}
	return -1;
}
TNODE* AST::GetNodeByStatementNumber(INTEGER statement_number){
	auto it= stmt_to_tnode.find(statement_number);
	if (it != stmt_to_tnode.end())
		return stmt_to_tnode.find(statement_number)->second;
	return NULL;
}